#include "../include/worker.h"
#include "../include/my_tlv.h"
#include "../include/threadPool.h"
#include "../include/user_manager.h"
#include "command.h"
#include "../include/netdisk.h"
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <sys/socket.h>
#include <unistd.h>

int tidArrInit(tidArr_t *ptidArr, int workerNum)
{
    // 初始化子线程数组就是申请workerNum个pthread_t个类型的内存
    ptidArr->arr = (pthread_t *)calloc(workerNum, sizeof(pthread_t));
    // 再把ptidArr的workerNum 初始化一下
    ptidArr->workerNum = workerNum;
    return 0;
}
void *threadFunc(void *arg)
{ // 目前子线程做命令匹配选择对应的服务
    threadPool_t *pthreadPool = (threadPool_t *)arg;
    usrArr_t one_user = {0};

    while (1)
    { // 持续接收客户端消息
        int netfd = -1;
        pthread_mutex_lock(&pthreadPool->mutex);
        while (pthreadPool->taskQueue.queueSize == 0)
        {
            pthread_cond_wait(&pthreadPool->cond, &pthreadPool->mutex);
        }
        deQueue(&pthreadPool->taskQueue, &netfd);
        pthread_mutex_unlock(&pthreadPool->mutex);
        // 收登录信息，用户名，明文密码
        train_t train_user = {0};

        int tag = recv(netfd, &train_user, sizeof(cmdstat_t) + sizeof(int), MSG_WAITALL);
        if (tag <= 0)
        {
            close(netfd);
            continue;
        }
        if (train_user.length <= 0)
        {
            close(netfd);
            continue;
        }

        int recv_len = recv(netfd, train_user.data, train_user.length, MSG_WAITALL);
        if (recv_len != 2048)
        {
            close(netfd);
            continue;
        }

        client_t user_data = {0};
        memcpy(&user_data, train_user.data, train_user.length);
        printf("usname:%s,pass:%s\n", user_data.Name, user_data.Password);
        tag = command_verif(user_data.Name, user_data.Password);
        if (tag == 1)
        {
            printf("密码错误\n");
            int ret = testLog(__LINE__, __FUNCTION__, __FILE__);
            if (ret == -1)
            {
                printf("open test.log failed: No such file or directory\n");
            }
            // 发给消息提示密码错误
            train_t info_result = {0};
            info_result.cmdstat = LOGIN;
            sprintf(info_result.data, "密码错误，请重新连接在尝试");
            info_result.length = strlen(info_result.data);
            // 验证用户密码不过给用户发个消息断开netfd，contiue
            send(netfd, &info_result,
                 sizeof(cmdstat_t) + sizeof(int) + info_result.length, MSG_NOSIGNAL);
            close(netfd);
            continue;
        }
        // 用户可以使用指令交互
        one_user.name = user_data.Name;
        char path[1024] = "/";
        one_user.path = path;
        if (tag == -1)
        {
            train_t info_result = {0};
            info_result.cmdstat = LOGIN;
            sprintf(info_result.data, "用户不存在");
            info_result.length = strlen(info_result.data);
            // 验证用户密码不过给用户发个消息断开netfd，contiue
            send(netfd, &info_result,
                 sizeof(cmdstat_t) + sizeof(int) + info_result.length, MSG_NOSIGNAL);
            close(netfd);
            continue;
        }
        char real_path[1024] = {0};
        sprintf(real_path, "%s/%s", DIST_DIR, one_user.name);
        if (access(real_path, F_OK))
        {
            commandResult_t result = {0};
            printf("mkdir:%s%s%s\n", DIST_DIR, "/", one_user.name);
            int cmd_r = command_mkdir(DIST_DIR, "/", one_user.name, &result);
            if (cmd_r != 0)
            {
                close(netfd);
                continue;
            }
            // name+/
            bzero(path, 1024);
            sprintf(path, "%s/", one_user.name);
            one_user.path = path;
        }

        train_t info_result = {0};
        info_result.cmdstat = LOGIN | IS_OK;
        sprintf(info_result.data, "欢迎");
        info_result.length = strlen(info_result.data);

        send(netfd, &info_result,
             sizeof(cmdstat_t) + sizeof(int) + info_result.length, MSG_NOSIGNAL);
        printf("用户登录成功\n");
        int flag = 1;
        while (flag)
        { // 持续处理客户端的命令
          // 接收客户端发送的 train_t 命令数据
            train_t train;
            memset(&train, 0, sizeof(train));
            ssize_t bytesReceived = recv(netfd, &train, sizeof(train.cmdstat) + sizeof(train.length), MSG_WAITALL);
            printf("%zd", bytesReceived);
            if (bytesReceived <= 0)
            {
                // 如果接收到的数据为0或负数，说明连接关闭或发生错误，退出循环
                printf("客户端断开连接或发生错误\n");
                break;
            }

            bytesReceived = recv(netfd, train.data, train.length, MSG_WAITALL);
            // 打印接收到的命令
            if (train.cmdstat != 0)
            {
                printf("接收到命令: %d, 路径: %s\n", train.cmdstat, train.data);
            }

            // ----必读----            
            int ret = 0;
            // 用于接收执行命令后的结果
            commandResult_t cmd_result = {0};
            // 用于存放发送客户端的数据
            train_t train_response = {0};
            // ----必读----

            // 使用 switch 判断命令类型
            switch (train.cmdstat)
            {
            case CD:
                printf("CD命令执行中...\n");
                initCommandResult(&cmd_result);
                memset(&train_response, 0 ,sizeof(train_response));
                ret = command_cd(DIST_DIR, one_user.name, one_user.path, &cmd_result);
                printf("ret = %d\n", ret);
                printf("%s \n", cmd_result.result);                
                if (ret != 0)
                {
                    train_response.cmdstat = CD;
                    train_response.length = strlen(cmd_result.result);
                    // printf("train_response.length = %d\n", train_response.length);
                    memcpy(train_response.data, cmd_result.result, train_response.length);
                    int ret = send(netfd, &train_response, sizeof(cmdstat_t) + sizeof(int) + train_response.length, MSG_NOSIGNAL);
                    printf("train_response.data = %s, ret = %d\n", train_response.data, ret);
                    if (ret <= 0)
                    {
                        close(netfd);
                        flag = 0;
                        break;
                    }
                    continue;
                }
                // 构建返回结果的火车协议包
                // 发送结果给客户端
                train_response.cmdstat = CD | IS_OK;
                train_response.length = strlen(*cmd_result.result_ls);
                memcpy(train_response.data, *cmd_result.result_ls, sizeof(train_response.length));
                int sret = send(netfd, &train_response, sizeof(cmdstat_t) + sizeof(int) + train_response.length, MSG_NOSIGNAL);
                if (sret <= 0)
                {
                    close(netfd);
                    flag = 0;
                    break;
                }
                break;
                break;
            case LS:
                printf("LS命令执行中...\n");               
                initCommandResult(&cmd_result);
                memset(&train_response, 0 ,sizeof(train_response));
                char current_dir[4096] = {0};
                strcpy(current_dir, one_user.name);
                char dest_dir[4096] = {0};
                strcpy(dest_dir, strtok(train.data, ""));
                command_ls(DIST_DIR, current_dir, dest_dir, &cmd_result);

                for (int i = 0; i < cmd_result.ls_linenum; i++)
                {
                    train_response.cmdstat = LS;
                    train_response.length = strlen(cmd_result.result_ls[i]);
                    strncpy(train_response.data, cmd_result.result_ls[i], train_response.length);
                    train_response.data[train_response.length] = '\0';
                    send(netfd, &train_response, sizeof(train_response.cmdstat) + sizeof(train_response.length) + train_response.length, MSG_NOSIGNAL);
                }
                memset(&train_response, 0, sizeof(train_response));
                train_response.cmdstat = OVER;
                send(netfd, &train_response.cmdstat, sizeof(train_response.cmdstat), MSG_NOSIGNAL);
                printf("LS命令执行完成\n");
                break;
            case PWD:
                printf("PWD命令执行中...\n");
                initCommandResult(&cmd_result);
                memset(&train_response, 0 ,sizeof(train_response));

                printf("LS命令执行完成\n");
                break;
            case MKDIR:
                printf("MKDIR命令执行中...\n");
                initCommandResult(&cmd_result);
                memset(&train_response, 0 ,sizeof(train_response));
                break;
            case RMDIR:
                printf("RMDIR命令执行中...\n");
                initCommandResult(&cmd_result);
                memset(&train_response, 0 ,sizeof(train_response));
                break;
            case PUTS:
            // 上传，接收客户端文件
                printf("PUTS命令执行中...\n");
                recv_from_sendfile(netfd);
                printf("PUTS命令执行完成\n");            
                break;
            case GETS:
            // 下载，发给客户端
                printf("GETS命令执行中...\n");
                printf("train.data = %s\n", train.data);
                transfer_file_by_sendfile(netfd, train.data);
                printf("GETS命令执行完成\n");
                break;
            case REMOVE:
                initCommandResult(&cmd_result);
                memset(&train_response, 0 ,sizeof(train_response));
                break;
            default:
                printf("不支持的命令: %d\n", train.cmdstat);
                break;
            }
        }
    }
    return NULL;
}
